package com.time.tell.the.truth.netty.client;

import com.time.tell.the.truth.netty.dto.User;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;

@Slf4j
public class ClientWriteHandler extends ChannelOutboundHandlerAdapter {

  // 协议格式如下：
  // | 报文总长度 | name长度 | name值 | age值 |
  // | 4字节     |   4字节  | --    |  4字节 |
  @Override
  public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
    User user = (User) msg;
    ByteBuf byteBuf = ctx.alloc().buffer();

    // 预留4个字节给 totalLength
    byteBuf.writerIndex(4);

    // 写名字
    byte[] nameBytes = user.getName().getBytes(StandardCharsets.UTF_8);
    byteBuf.writeInt(nameBytes.length);
    byteBuf.writeBytes(nameBytes);

    // 写年龄
    byteBuf.writeInt(user.getAge());

    // 设置报文总长度
    int totalLength = byteBuf.writerIndex();
    byteBuf.setInt(0, totalLength);

//    和上面的byteBuf.setInt(0, totalLength)等价
//    byteBuf.markWriterIndex();
//    byteBuf.writerIndex(0);
//    byteBuf.writeInt(totalLength);
//    byteBuf.resetWriterIndex();

    // 继续执行后续handler
    ctx.writeAndFlush(byteBuf, promise)
        .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
    log.info("send user to server {}", user);
  }
}
